package club.bigtian.statusbar;

import com.intellij.credentialStore.CredentialAttributes;
import com.intellij.credentialStore.CredentialAttributesKt;
import com.intellij.credentialStore.Credentials;
import com.intellij.ide.passwordSafe.PasswordSafe;
import com.intellij.openapi.application.ApplicationManager;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * 凭证管理器
 * 用于保存和管理Augment插件的认证凭证
 */
public class CredentialManager {
    private static final String SUBSYSTEM_NAME = "augment oauth";
    private static final String AUGMENT_OAUTH_STATE_CLASS = "com.augmentcode.intellij.auth.AugmentOAuthState";
    private static final String AUGMENT_CREDENTIALS_CLASS = "com.augmentcode.intellij.auth.AugmentCredentials";
    private static final String SAVE_CREDENTIALS_METHOD = "saveCredentials";
    private static final String CLEAR_METHOD = "clear";
    private static Class<?> augmentOAuthStateClass;
    private static Class<?> augmentCredentialsClass;
    private static Constructor<?> credentialsConstructor;
    private static Method saveCredentialsMethod;
    private static Method clearMethod;
    private final CredentialAttributes credentialAttributes = new CredentialAttributes(
        CredentialAttributesKt.generateServiceName(SUBSYSTEM_NAME, "credentials")
    );
    private Object AUGMENT_OAUTH_STATE_INSTANCE;

    public void saveCredentials(String tenantUrl, String authToken) {
        PasswordSafe.Companion.getInstance().set(this.credentialAttributes, new Credentials(tenantUrl, authToken));
    }

    public Credentials getCredentials() {
        return PasswordSafe.Companion.getInstance().get(this.credentialAttributes);
    }

    public String getTenantUrl() {
        Credentials credentials = this.getCredentials();
        return credentials != null && credentials.getUserName() != null ? credentials.getUserName() : "";
    }

    public String getAuthToken() {
        Credentials credentials = this.getCredentials();
        return credentials != null && credentials.getPasswordAsString() != null ? credentials.getPasswordAsString() : "";
    }

    public void clearCredentials() {
        PasswordSafe.Companion.getInstance().set(this.credentialAttributes, (Credentials)null);
    }

    public void reflectionClear() {
        try {
            this.initReflectionClasses();
            if (this.AUGMENT_OAUTH_STATE_INSTANCE == null) {
                System.out.println("Failed to Get AugmentOAuthState Service Instance");
                return;
            }

            clearMethod.invoke(this.AUGMENT_OAUTH_STATE_INSTANCE);
            System.out.println("Successfully Clear Augment Credentials via Reflection");
        } catch (ClassNotFoundException e) {
            System.out.println("Augment Plugin Not Found, Please Install Augment Plugin: " + e.getMessage());
        } catch (NoSuchMethodException e) {
            System.out.println("Augment Plugin API Changed, Required Method Not Found: " + e.getMessage());
        } catch (NoClassDefFoundError e) {
            System.out.println("Augment Plugin Classes Not Available: " + e.getMessage());
        } catch (NoSuchMethodError e) {
            System.out.println("Augment Plugin Method Not Available (API incompatibility): " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Clear Augment Credentials Error: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 通过反射保存凭证到Augment插件
     * @param tenantURL 租户URL
     * @param authToken 认证Token
     */
    public void reflectionSaveCredentials(String tenantURL, String authToken) {
        try {
            this.initReflectionClasses();
            if (this.AUGMENT_OAUTH_STATE_INSTANCE == null) {
                System.out.println("Failed to Get AugmentOAuthState Service Instance");
                return;
            }

            Object newCredentials = credentialsConstructor.newInstance(authToken, tenantURL);
            saveCredentialsMethod.invoke(this.AUGMENT_OAUTH_STATE_INSTANCE, newCredentials);
            System.out.println("Successfully Updated Augment Credentials via Reflection");
        } catch (ClassNotFoundException e) {
            System.out.println("Augment Plugin Not Found, Please Install Augment Plugin: " + e.getMessage());
        } catch (NoSuchMethodException e) {
            System.out.println("Augment Plugin API Changed, Required Method Not Found: " + e.getMessage());
        } catch (NoClassDefFoundError e) {
            System.out.println("Augment Plugin Classes Not Available: " + e.getMessage());
        } catch (NoSuchMethodError e) {
            System.out.println("Augment Plugin Method Not Available (API incompatibility): " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Update Augment Credentials Error: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private void initReflectionClasses() throws ClassNotFoundException, NoSuchMethodException {
        if (augmentOAuthStateClass == null) {
            augmentOAuthStateClass = Class.forName(AUGMENT_OAUTH_STATE_CLASS);
        }

        if (this.AUGMENT_OAUTH_STATE_INSTANCE == null) {
            this.AUGMENT_OAUTH_STATE_INSTANCE = ApplicationManager.getApplication().getService(augmentOAuthStateClass);
        }

        if (augmentCredentialsClass == null) {
            augmentCredentialsClass = Class.forName(AUGMENT_CREDENTIALS_CLASS);
        }

        if (credentialsConstructor == null) {
            credentialsConstructor = augmentCredentialsClass.getConstructor(String.class, String.class);
        }

        if (saveCredentialsMethod == null) {
            saveCredentialsMethod = augmentOAuthStateClass.getDeclaredMethod(SAVE_CREDENTIALS_METHOD, augmentCredentialsClass);
        }

        if (clearMethod == null) {
            clearMethod = augmentOAuthStateClass.getDeclaredMethod(CLEAR_METHOD);
        }
    }
}

